#+TITLE: i3wm Config
#+DESCRIPTION: Literate config for my the i3 window manager
#+PROPERTY: header-args :tangle ~/.config/i3/config :results silent

This file contains all my personal configuration options for i3wm.

* Header

#+BEGIN_SRC conf
# i3 config file (v4)
#
# Please see http://i3wm.org/docs/userguide.html for a complete reference!
#+END_SRC


* Keybindings

All my keybinds are stored in this section. Although I use i3wm, my first tiling window manager was xmonad. The configuration in Haskell /sucked/, but I liked the keybinds so this setup is quite simiar to xmonad defaults.

** Main Modifier Key

Use the "super" key as the main modifier key

#+BEGIN_SRC conf
set $mod Mod4
#+END_SRC

** Window Managment

*** Launch new terminal window

Super+Return will open a new terminal window, the command i3-sensible-terminal will choose one installed. Generally I use terminator, but if thats not available this will still launch something.

#+BEGIN_SRC conf
bindsym $mod+Return exec i3-sensible-terminal
#+END_SRC

*** Program Launcher

I currently use Rofi to launch programs. Much more versatile than dmenu, but can still emulate it. Super+p will let you choose a program, Super+Shift+p is the same, but running it via Optimus. This provides the discrete Nvidia GPU to that application as I use on my Thinkpad W520

#+BEGIN_SRC conf
bindsym $mod+p exec rofi -show drun -sidebar-mode true
bindsym $mod+Shift+p exec rofi -show combi -run-command "primusrun {cmd}" -display-combi "Primus Run" -display-run "Priimus binary" -display-drun "Primus application"
#+END_SRC

*** Window Focus

Use Super and the directin keys to change focus between windows

#+BEGIN_SRC conf
bindsym $mod+Left focus left
bindsym $mod+Down focus down
bindsym $mod+Up focus up
bindsym $mod+Right focus right
#+END_SRC

**** Disable Mouse Focus

The below prevents mouse movement from chanigng focus as the mouse moves (clicking an unfocused window will still give focus, however.

#+BEGIN_SRC conf
focus_follows_mouse no
#+END_SRC

**** One-Handed Navigation Mode

I have implemented a 1 handed navigation mode. Super+z enters the mode, then windows can be moved in the current workspace with just direction keys - or moved to anotehr workspace with just a number key. When finished, hit Return, Escape, or Super+z to return to normal operation.

#+BEGIN_SRC conf
mode "navigate" {
    bindsym Left focus left
    bindsym Down focus down
    bindsym Up focus up
    bindsym Right focus right

    bindsym 1 workspace 1
    bindsym 2 workspace 2
    bindsym 3 workspace 3
    bindsym 4 workspace 4
    bindsym 5 workspace 5
    bindsym 6 workspace 6
    bindsym 7 workspace 7
    bindsym 8 workspace 8
    bindsym 9 workspace 9
    bindsym 0 workspace 10

    bindsym Return mode "default"
    bindsym Escape mode "default"
    bindsym $mod+z mode "default"
}

bindsym $mod+z mode "navigate"
#+END_SRC

*** Moving Windows

**** Within Workspace

Super+Shift+ direction keys will move the current window around the current workspace

#+BEGIN_SRC conf
bindsym $mod+Shift+Left move left
bindsym $mod+Shift+Down move down
bindsym $mod+Shift+Up move up
bindsym $mod+Shift+Right move right
#+END_SRC

**** Changing Workspaces

Super+Shift+ number (0-9) will move the current window to the specified workspace

#+BEGIN_SRC conf
bindsym $mod+Shift+1 move container to workspace 1
bindsym $mod+Shift+2 move container to workspace 2
bindsym $mod+Shift+3 move container to workspace 3
bindsym $mod+Shift+4 move container to workspace 4
bindsym $mod+Shift+5 move container to workspace 5
bindsym $mod+Shift+6 move container to workspace 6
bindsym $mod+Shift+7 move container to workspace 7
bindsym $mod+Shift+8 move container to workspace 8
bindsym $mod+Shift+9 move container to workspace 9
bindsym $mod+Shift+0 move container to workspace 10
#+END_SRC

*** Resizing Windows

Resizing windows is achieved by first hitting Super+r to get into "resize" mode. Then the arrow keys are used to strech/shrink the current window. When finished, hit Return, Escape, or Super+r to return to normal operation

#+BEGIN_SRC conf
mode "resize" {
    bindsym Left resize shrink width 2 px or 2 ppt
    bindsym Down resize grow height 2 px or 2 ppt
    bindsym Up resize shrink height 2 px or 2 ppt
    bindsym Right resize grow width 2 px or 2 ppt
    bindsym Return mode "default"
    bindsym Escape mode "default"
    bindsym $mod+r mode "default"
}

bindsym $mod+r mode "resize"
#+END_SRC

*** Fullscreen Mode

Super+f will toggle fullscreen mode for the current window

#+BEGIN_SRC conf
bindsym $mod+f fullscreen toggle
#+END_SRC

*** Closing windows

Super+Shift+c is used to close windows

#+BEGIN_SRC conf
bindsym $mod+Shift+c kill
#+END_SRC

*** Floating Windows

**** Toggle Floating

Super+Shift+Space will toggle the current window between tiled and floating

#+BEGIN_SRC conf
bindsym $mod+Shift+space floating toggle
#+END_SRC

**** Floating Focus

Super+Space will switch focus between floating windows and tiled windows on the current workspace

#+BEGIN_SRC conf
bindsym $mod+space focus mode_toggle
#+END_SRC

**** Moving Floating Windows

Use the standard modifier to move floating windows around

#+BEGIN_SRC conf
floating_modifier $mod
#+END_SRC

** Workspace Management

*** Change Workspace

Super+ number (0-9) will switch to view the selected workspace

#+BEGIN_SRC conf
bindsym $mod+1 workspace 1
bindsym $mod+2 workspace 2
bindsym $mod+3 workspace 3
bindsym $mod+4 workspace 4
bindsym $mod+5 workspace 5
bindsym $mod+6 workspace 6
bindsym $mod+7 workspace 7
bindsym $mod+8 workspace 8
bindsym $mod+9 workspace 9
bindsym $mod+0 workspace 10
#+END_SRC

*** Workspace Split

To change the way the workspace/container will split for the next terminal/program, you have the following options:-

- Super+h - Horizontal Split
- Super+v - Veritcal Split

#+BEGIN_SRC conf
bindsym $mod+h split h
bindsym $mod+v split v
#+END_SRC

*** Workspace Layouts

Overall workspace/container layouts can be changed with the following options:-

- Super+n - Stacked layout
- Super+m - Tabbed layout
- Super+b - Tiled layout (also toggles between Horizontal/Vertical splits)

#+BEGIN_SRC conf
bindsym $mod+n layout stacking
bindsym $mod+m layout tabbed
bindsym $mod+b layout toggle split
#+END_SRC

** i3wm Management

These keybinds effect i3wm itself

*** Reload Configuration

Super+q will reload the coniguration in place

#+BEGIN_SRC conf
bindsym $mod+q reload
#+END_SRC

*** Restart i3 in-place

Super+Shift+q restarts the window manager, but keeping layout and programs running

#+BEGIN_SRC conf
bindsym $mod+Shift+q restart
#+END_SRC

*** Exit i3wm

Super+Shift+Escape closes i3wm completely, and logs out of the current X session - but uses the "nagbar" to confirm choice before killing everything

#+BEGIN_SRC conf
bindsym $mod+Shift+Escape exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'"
#+END_SRC

** Lock Screen

Super+l locks the screen with light-locker

#+BEGIN_SRC conf
bindsym $mod+l exec light-locker-command -l
#+END_SRC

** Take Screenshot

Super+PrtScr will use ~flameshot~ to take a screenshot, passing the gui argument as the command alone only starts the daemon and puts a sysicon in the tray

#+BEGIN_SRC conf
bindsym $mod+Print exec flameshot gui
#+END_SRC

*** Video Screenshot

Super+Shift+PrtScr will load SimpleScreenRecorder to quickly record a video of the desktop

#+BEGIN_SRC conf
bindsym $mod+Shift+Print exec simplescreenrecorder
#+END_SRC

** Thinkpad W520 - Extra Keys

There are several media keys available on my ThinkPad keyboard, the below control how these react

*** Volume Controls

Volume up/down, mute, and mic mute work as expected with Pulse Audio

#+BEGIN_SRC conf
bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume 0 +5% # Increase Volume
bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume 0 -5% # Decrease Volume
bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute 0 toggle # Mute Sound
bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute 1 toggle # Disable Microphone
#+END_SRC

*** TODO Lock Screen/Suspend

These eys are behind Fn and F2/F4 - lock screen works as expected, suspend has been commented out as not currently working as expected...

#+BEGIN_SRC conf
bindsym XF86ScreenSaver exec light-locker-command -l

#bindsym XF86WakeUp exec --no-startup-id systemctl suspend
#+END_SRC

*** Media Controls

Media controls behind Fn+ direction keys (work as expected)

#+BEGIN_SRC conf
bindsym XF86AudioPlay exec playerctl play
bindsym XF86AudioPause exec playerctl pause
bindsym XF86AudioNext exec playerctl next
bindsym XF86AudioPrev exec playerctl previous
#+END_SRC


* Visuals

** Fonts

My chosen font is the Literation Mono Nerd Font, which should be backed up with my dotfiles. I use this throughout most applications (emacs/terminal emulators/rofi etc), so this will set it to be used for window title bars.

#+BEGIN_SRC conf
font pango:LiterationMono Nerd Font 9
#+END_SRC

** Window Colouring

The below defines the green & grey colour scheme I prefer, with the red for urgent items. Comment line left in to help decipher which hexcode is which.

#+BEGIN_SRC conf
# class                 border  backgr. text    indicator child_border
client.focused          #04f700 #196d13 #ffffff #50bf1c   #6de835
client.focused_inactive #333333 #5f676a #ffffff #484e50   #5f676a
client.unfocused        #333333 #222222 #888888 #292d2e   #222222
client.urgent           #ff0000 #700e0e #ffffff #ff0000   #ff0000
client.placeholder      #000000 #0c0c0c #ffffff #000000   #0c0c0c

client.background       #ffffff
#+END_SRC

** Smart Borders

Only show window borders when multiple windows are open, to keep clean looks

#+BEGIN_SRC conf
hide_edge_borders smart
#+END_SRC

** Urgency Hint

Make urgency hint visible for 1 second

#+BEGIN_SRC conf
force_display_urgency_hint 1000 ms
#+END_SRC

** Transparency

Transparency for unfocused windows is handled by the compton compositor, which is invoked in the [[*Compton Compositor][Autostarts section]] of this config

** Wallpaper

Nitrogen is used to handle the wallpaper, and this is found in the [[*Nitrogen Wallpaper Manager][Autostarts]] of this config

** Status Bars/Panels

These are all handled with [[*Polybar Panels][Polybar]], launched in the Autostarts

* Floating Windows

The below sections define window types/classes to be forced into floating mode. i3 is generally quite smart with floating windows, if windows are properly defined in gtk/qt/etc, but some that /should/ be floating take up a normal container in the tiling.

Details of the criteria (in square brackets) can be found in the [[https://i3wm.org/docs/userguide.html#command_criteria][i3wm documentation]].
To find out Class/instance info run ~xprop | grep WM_CLASS~ and click on the window in question.

** Thunderbird

#+BEGIN_SRC conf
for_window [class="Mailnews"] floating enable
for_window [class="Msgcompose"] floating enable
#+END_SRC

** Pulse Audio Volume Control

#+BEGIN_SRC conf
for_window [class="Pavucontrol"] floating enable
#+END_SRC

** JACK Audio Connection Kit Dashboard

#+BEGIN_SRC conf
for_window [class="qjackctl"] floating enable
#+END_SRC

** Virtual MIDI Keyboard

#+BEGIN_SRC conf
for_window [class="Vkeybd.tcl" instance="vkeybd.tcl"] floating enable
#+END_SRC

** JACK Keyboard

#+BEGIN_SRC conf
for_window [class="jack-keyboard"] floating enable
#+END_SRC

** FluidSynth

#+BEGIN_SRC conf
for_window [class="FluidSynth-DSSI_gtk"] floating enable
#+END_SRC

** FontPreviewer

#+BEGIN_SRC conf
for_window [class="Display-im6.q16"] floating enable move position center
#+END_SRC

** Steam

#+BEGIN_SRC conf
for_window [class="Steam" title="Friends List"] floating enable
for_window [class="Steam" title="Zebediela"] floating enable
#+END_SRC

** GZDoom Wad Selector

#+BEGIN_SRC conf
for_window [class="Gzdoom"] floating enable move position center
#+END_SRC

** GURPS Character Creator

#+BEGIN_SRC conf
for_window [class="com-trollworks-gcs-GCS"] floating enable move position center
for_window [class="com-trollworks-gcs-GCS" title="GCS"] floating disable
#+END_SRC

** Galculator

#+BEGIN_SRC conf
for_window [class="Galculator"] floating enable
#+END_SRC

** scrcpy

Android device mirroring

#+BEGIN_SRC conf
for_window [class="scrcpy"] floating enable
#+END_SRC

** SimpleScreenRecorder

#+BEGIN_SRC conf
for_window [class="SimpleScreenRecorder"] floating enable
#+END_SRC

** Flowblade Rendering

#+BEGIN_SRC conf
for_window [class="Flowbladesinglerender"] floating enable
#+END_SRC

** Yad dialogs

#+BEGIN_SRC conf
for_window [class="Yad"] floating enable
#+END_SRC


* Autostarts

The below commands automatically start required software/scripts when logging in to i3wm

** Compton Compositor

This uses the compton compositor to allow transparency effects for unfocused windows

#+BEGIN_SRC conf
exec --no-startup-id compton --sw-opti -i 0.85 --active-opacity 0.999 -f -c -D 3 -b
#+END_SRC

** Nitrogen Wallpaper Manager

#+BEGIN_SRC conf
exec_always nitrogen --set-centered ~/Pictures/wallpapers/greenhex-larger.jpg
#+END_SRC

** Power Manager

xfce4 powermanager is used to handle hibernation etc

#+BEGIN_SRC conf
exec_always xfce4-power-manager
#+END_SRC

** light-locker screen lock

#+BEGIN_SRC conf
exec_always light-locker
#+END_SRC

** Polybar Panels

#+BEGIN_SRC conf
exec_always --no-startup-id $HOME/bin/polylaunch.sh
#+END_SRC

** Network Manager Applet

#+BEGIN_SRC conf
exec_always nm-applet
#+END_SRC

** Bluetooth Tray Applet

#+BEGIN_SRC conf
exec_always blueman-applet
#+END_SRC

** Flameshot Tray Applet

#+BEGIN_SRC conf
exec_always flameshot
#+END_SRC

** Redshift Colour Manager

#+BEGIN_SRC conf
exec redshift-gtk
#+END_SRC

** Unclutter

This hides the mouse pointer when not used for 5 seconds

#+BEGIN_SRC conf
exec unclutter -idle 5 -noevents -reset
#+END_SRC

** PolicyKit - Authentication

This provides a modern version of gksudo, along with fingerprint management

#+BEGIN_SRC conf
exec_always /usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1
#+END_SRC

** Syncthing

#+BEGIN_SRC conf
exec syncthing-gtk
#+END_SRC

** Emacs Daemon

Launch emacs as a server, so I can have multiple sessions acccessed with emacslient.

The XMODIFIERS variable allows the compose key binding to work, which is set in my ~.bashrc~

#+BEGIN_SRC conf
exec_always XMODIFIERS=@im=none emacs --daemon
#+END_SRC


